package com.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.api.ApprovalApi;
import com.common.api.CommonFileApi;
import com.common.core.domain.AjaxResult;
import com.common.core.domain.entity.SysUser;
import com.common.utils.DateUtils;
import com.common.utils.QueryWrapperUtils;
import com.common.utils.SecurityUtils;
import com.common.utils.StringUtils;
import com.common.utils.bean.BizProcessMessages;
import com.domain.dto.KycxAuthorDTO;
import com.domain.dto.KycxDTO;
import com.domain.entity.KycxZl;
import com.domain.param.KycxParam;
import com.domain.vo.KycxAuthorVO;
import com.domain.vo.KycxVo;
import com.domain.vo.KycxZlVo;
import com.flowable.domain.vo.task.BpmTaskApproveReqVO;
import com.flowable.service.IFlowTaskService;
import com.mapper.KyckZlMapper;
import com.mapping.KyckMapping;
import com.service.IKycxAuthorService;
import com.service.IKycxZlService;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class KycxZlServiceImpl extends ServiceImpl<KyckZlMapper, KycxZl> implements IKycxZlService {

    @Autowired
    private KyckMapping mapping;

    @Autowired
    private IKycxAuthorService authorService;

    //发起审批
    @Autowired
    private ApprovalApi approvalApi;

    //流程引擎
    @Autowired
    private IFlowTaskService flowTaskService;

    //通用文件api
    @Autowired
    private CommonFileApi fileApi;
    private final static String module_name = "专利诚信";

    @Override
    public void updateBusinessStatus(String tableName, String businessId, String checkStatus, String sysUserId) {
        if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(businessId) || StringUtils.isEmpty(checkStatus))
            return;
        KycxZl entity = new KycxZl();
        entity.setId(businessId);
        entity.setCheckstatus(checkStatus);
        if ("2".equals(checkStatus)) {
            entity.setCheckdate(DateUtils.getTime());
            entity.setChecker(SecurityUtils.getNickName());
        }
        this.updateById(entity);
    }


    @Override
    public List<KycxVo> selectByPage(KycxParam param) {

        LambdaQueryWrapper<KycxZl> queryWrapper = buildQueryWrapper(param);
        QueryWrapperUtils.getParams_kycx(queryWrapper,SecurityUtils.getLoginUser().getUser());

        List<KycxVo> KycxList = this.baseMapper.getList(param, queryWrapper);
        //获取当前用户所有的代办列表
        Map<String, String> instanceTaskMap = approvalApi.getInstanceTaskMap(module_name);
        KycxList.stream().forEach(a -> {
            // 判断是否是审核人，并设置taskId
            String processInstanceId = a.getProcessInstanceId();
            if (StringUtils.isNotEmpty(processInstanceId) && instanceTaskMap.containsKey(processInstanceId)) {
                a.setTaskId(instanceTaskMap.get(processInstanceId));
                a.setIsAuditor(true);
            } else {
                a.setIsAuditor(false);
            }
        });
        return KycxList;
    }



    @Override
    public List<KycxZlVo> selectByExport_zl(KycxParam param) {
        LambdaQueryWrapper<KycxZl> queryWrapper  = buildQueryWrapper(param);
        QueryWrapperUtils.getParams_kycx(queryWrapper, SecurityUtils.getLoginUser().getUser());
        return this.baseMapper.getListByExport_zl(param, queryWrapper);

    }


    @Override
    public KycxVo getInfoById(String id) {

        KycxZl entity = this.getById(id);
        if (ObjectUtil.isNull(entity)) {
            return new KycxVo();
        }
        KycxVo KycxVO = mapping.zlEntity2Vo(entity);
        //文件名
        String fileName = fileApi.getFileName(KycxVO.getFileId());
        KycxVO.setFileName(fileName);

        //查询论文作者列表信息
        List<KycxAuthorVO> authorVOList = authorService.getInfoByKycxId(id);

        KycxVO.setAuthorList(authorVOList);

        return KycxVO;
    }

    @Override
    public AjaxResult add(KycxDTO dto) {
        List<KycxAuthorDTO> authorList = dto.getAuthorList();

        //基本信息
        KycxZl entity = mapping.dto2ZlEntity(dto);
        String UUID = IdUtil.randomUUID().replace("-", "");
        entity.setId(UUID);

        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        entity.setCreateUserId(loginUser.getUserRealId());
        entity.setCreateUserName(loginUser.getNickName());

        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            entity.setCreateDate(dateFormat.parse(dateFormat.format(date)));
        } catch (ParseException e) {

        }

        String authorIds = authorList.stream().map(KycxAuthorDTO::getPersonId)
                .filter(pid -> pid != null && !pid.isEmpty()) //排除掉空的情况
                .collect(Collectors.joining(","));
        entity.setAuthorIds(authorIds);

        //给每个作者加上论文ID
        authorList.forEach(e->{
            e.setKycxId(UUID);
        });

        Integer submitType = dto.getSubmitType();

        switch (submitType) {
            case 2: // 保存并通过
                entity.setProcessInstanceId("0");
                entity.setCheckstatus(String.valueOf(submitType));
                entity.setCheckdate(DateUtils.getTime());
                entity.setChecker(SecurityUtils.getNickName());
                break;
            case 1: // 提交
                entity.setCheckstatus(String.valueOf(submitType));
                if (!(this.save(entity) && authorService.add(authorList))) {
                    return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
                }
                String processInstanceId = null;
                try {
                    //发起流程 业务状态由流程引擎更新
                    processInstanceId = approvalApi.businessEntryApproval(entity.getId(), module_name);
                } catch (Exception e) {
                    AjaxResult.error(BizProcessMessages.SAVE_PARTIAL_SUCCESS);
                }

                return StringUtils.isEmpty(processInstanceId)
                        ? AjaxResult.error(BizProcessMessages.SAVE_PARTIAL_SUCCESS)
                        : AjaxResult.success((Object)entity.getId());
            default: // 处理 -1（暂存）及其他情况
                entity.setCheckstatus(String.valueOf(submitType));
                break;
        }


        boolean r = this.save(entity)
                && authorService.add(dto.getAuthorList());
        return r ? AjaxResult.success((Object)entity.getId()) : AjaxResult.error(BizProcessMessages.SAVE_FAIL);
    }


    @Override
    public AjaxResult update(KycxDTO dto) {
        List<KycxAuthorDTO> authorList = dto.getAuthorList();
        //处理旧文件
        String id = dto.getId();
        KycxZl oldKycxLw = this.getById(id);
        String newFileId = dto.getFileId();
        String oldFileId = oldKycxLw.getFileId();
        //替换了文件
        if (StringUtils.isNotEmpty(oldFileId) && StringUtils.isNotEmpty(newFileId) && !newFileId.equals(oldFileId)) {
            fileApi.delFile(oldFileId);
            //文件从有到无
        } else if (StringUtils.isNotEmpty(oldFileId) && StringUtils.isEmpty(newFileId)) {
            fileApi.delFile(oldFileId);
        }

        KycxZl entity = mapping.dto2ZlEntity(dto);
        String authorpids = authorList.stream().map(a -> a.getPersonId())
                .filter(pid -> pid != null && !pid.isEmpty()) //排除掉空的情况
                .collect(Collectors.joining(","));
        entity.setAuthorIds(authorpids);
        SysUser loginUser = SecurityUtils.getLoginUser().getUser();
        entity.setLastEditUserId(loginUser.getUserRealId());
        entity.setLastEditUserName(loginUser.getNickName());

        Date date = new Date();
        SimpleDateFormat dateFormat= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            entity.setLastEditDate(dateFormat.parse(dateFormat.format(date)));
        } catch (ParseException e) {

        }
        //新增论文作者信息
        //根据论文 kycxId，删除作者信息，再新增作者信息
        authorService.deleteByKycxId(entity.getId());

        //给每个作者加上论文ID
        authorList.forEach(e->{
            e.setKycxId(entity.getId());
        });

        Integer submitType = dto.getSubmitType();

        switch (submitType) {
            case 2: // 保存并通过
                // 当前用户是否是审批人
                boolean isAuditor = dto.getIsAuditor();
                // 审批人直接审核（仅适用于提交类型2且为当前审核人的情况）
                if (isAuditor) {
                    if (this.updateById(entity)&& authorService.add(authorList)) {
                        BpmTaskApproveReqVO bta = new BpmTaskApproveReqVO();
                        bta.setId(dto.getTaskId());
                        bta.setReason(SecurityUtils.getNickName() + "保存并通过");
                        try {
                            flowTaskService.approveTask(SecurityUtils.getUserId(), bta);
                        } catch (Exception e) {
                            return AjaxResult.error(BizProcessMessages.SAVE_SUCCESS_APPROVE_FAIL, e.getMessage());
                        }

                        return AjaxResult.success(BizProcessMessages.SAVE_SUCCESS);
                    }
                    return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
                }
                //处理非当前审批人保存并通过
                if (!("2").equals(dto.getCheckstatus())){
                    entity.setProcessInstanceId("0");
                }
                entity.setCheckdate(DateUtils.getTime());
                entity.setChecker(SecurityUtils.getNickName());
                //只有管理员才会有非当前审核人的情况下有 "保存并提交"按钮,审核完后的结果只能是审核通过
                entity.setCheckstatus(String.valueOf(submitType));
                break;
            case 1:
                //暂存转提交
                if (!(this.updateById(entity)&& authorService.add(authorList))) {
                    return AjaxResult.error(BizProcessMessages.SAVE_FAIL);
                }
                String returnProcessInstanceId = null;
                try {
                    returnProcessInstanceId = approvalApi.businessEntryApproval(entity.getId(), module_name);
                } catch (Exception e) {
                    return AjaxResult.error(BizProcessMessages.SAVE_PARTIAL_SUCCESS, e.getMessage());
                }

                return StringUtils.isEmpty(returnProcessInstanceId)
                        ? AjaxResult.warn(BizProcessMessages.SAVE_PARTIAL_SUCCESS)
                        : AjaxResult.success(BizProcessMessages.SAVE_SUCCESS);
            case -1: // 暂存
                return this.updateById(entity) && authorService.add(authorList)
                        ? AjaxResult.success(BizProcessMessages.SAVE_SUCCESS)
                        : AjaxResult.error(BizProcessMessages.SAVE_FAIL);
            default:
                break;
        }

        return this.updateById(entity) && authorService.add(authorList)
                ? AjaxResult.success(BizProcessMessages.SAVE_SUCCESS)
                : AjaxResult.error(BizProcessMessages.SAVE_FAIL);
    }

    @Override
    public boolean batchRemove(List<String> ids) {
        //删除作者
       authorService.deleteByKycxIdList(ids);
        for (String id : ids) {
            KycxZl Kycx = this.getById(id);
            if (Kycx != null && StringUtils.isNotEmpty(Kycx.getFileId())) {
                try {
                    fileApi.delFile(Kycx.getFileId());
                } catch (Exception e) {
                    log.error("删除文件失败，fileId：" + id, e);
                }
            }
        }
        return this.removeByIds(ids);
    }

    @Override
    public List<HashMap<String, Integer>> listStatistics(KycxParam param) {

        LambdaQueryWrapper<KycxZl> queryWrapper =buildQueryWrapper(param);
        QueryWrapperUtils.getParams_kycx(queryWrapper, SecurityUtils.getLoginUser().getUser());

        return this.baseMapper.listStatistics(param, queryWrapper);
    }

    private LambdaQueryWrapper<KycxZl> buildQueryWrapper(KycxParam param) {
        LambdaQueryWrapper<KycxZl> queryWrapper = new LambdaQueryWrapper<>();
        if (param == null) return queryWrapper;

        //状态
        queryWrapper.eq(StringUtils.isNotEmpty(param.getCheckstatus()), KycxZl::getCheckstatus, param.getCheckstatus());
       //专利名称
        queryWrapper.apply(StringUtils.isNotEmpty(param.getName()), "kycx.name like concat('%', {0}, '%')", param.getName());
        //专利类型 - 多值
        queryWrapper.in(StringUtils.isNotEmpty(param.getModeIdList()), KycxZl::getModeId, param.getModeIdList());
        //所属单位 - 多值
        queryWrapper.in(StringUtils.isNotEmpty(param.getPublishUnitList()), KycxZl::getPublishUnit, param.getPublishUnitList());
        //一级学科 - 多值
        if (ArrayUtils.isNotEmpty(param.getSubjectIdList())) {
            String inSql = Arrays.stream(param.getSubjectIdList())
                    .map(id -> "'" + id + "'") // 加引号
                    .collect(Collectors.joining(","));
            queryWrapper.apply("kycx.subject_id in (" + inSql + ")");
        }
        //检索时间起始
        queryWrapper.ge(StringUtils.isNotEmpty(param.getPublishDateStart()), KycxZl::getPublishDate, param.getPublishDateStart());
        //检索时间截止
        queryWrapper.le(StringUtils.isNotEmpty(param.getPublishDateEnd()), KycxZl::getPublishDate, param.getPublishDateEnd());
        //登记人
        queryWrapper.apply(StringUtils.isNotEmpty(param.getCreateusername()), "kycx.CREATEUSERNAME like concat('%', {0}, '%')", param.getCreateusername());
        return queryWrapper;
    }
}
